/*
 * Copyright (c) Mirth Corporation. All rights reserved.
 * 
 * http://www.mirthcorp.com
 * 
 * The software in this package is published under the terms of the MPL license a copy of which has
 * been included with this distribution in the LICENSE.txt file.
 */

package com.mirth.connect.connectors.js;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.EvaluatorException;

import com.mirth.connect.client.ui.UIConstants;
import com.mirth.connect.client.ui.VariableListHandler.TransferMode;
import com.mirth.connect.client.ui.panels.connectors.ConnectorSettingsPanel;
import com.mirth.connect.donkey.model.channel.ConnectorProperties;
import com.mirth.connect.model.codetemplates.ContextType;
import com.mirth.connect.util.JavaScriptSharedUtil;

public class JavaScriptWriter extends ConnectorSettingsPanel {

    public JavaScriptWriter() {
        initComponents();
    }

    @Override
    public String getConnectorName() {
        return new JavaScriptDispatcherProperties().getName();
    }

    @Override
    public ConnectorProperties getProperties() {
        JavaScriptDispatcherProperties properties = new JavaScriptDispatcherProperties();

        properties.setScript(javaScriptTextScrollPane.getText());

        return properties;
    }

    @Override
    public void setProperties(ConnectorProperties properties) {
        JavaScriptDispatcherProperties props = (JavaScriptDispatcherProperties) properties;

        javaScriptTextScrollPane.setText(props.getScript());
    }

    @Override
    public ConnectorProperties getDefaults() {
        return new JavaScriptDispatcherProperties();
    }

    @Override
    public boolean checkProperties(ConnectorProperties properties, boolean highlight) {
        JavaScriptDispatcherProperties props = (JavaScriptDispatcherProperties) properties;

        boolean valid = true;

        if (props.getScript().length() == 0) {
            valid = false;
            if (highlight) {
                javaScriptTextScrollPane.setBackground(UIConstants.INVALID_COLOR);
            }
        }

        return valid;
    }

    public TransferMode getTransferMode() {
        return TransferMode.JAVASCRIPT;
    }

    @Override
    public void resetInvalidProperties() {
        javaScriptTextScrollPane.setBackground(null);
    }

    @Override
    public void setVisible(boolean aFlag) {
        super.setVisible(aFlag);
        javaScriptTextScrollPane.updateDisplayOptions();
    }

    @Override
    public String doValidate(ConnectorProperties properties, boolean highlight) {
        JavaScriptDispatcherProperties props = (JavaScriptDispatcherProperties) properties;

        String error = null;

        String script = props.getScript();

        if (script.length() != 0) {
            Context context = JavaScriptSharedUtil.getGlobalContextForValidation();
            try {
                context.compileString("function rhinoWrapper() {" + script + "\n}", UUID.randomUUID().toString(), 1, null);
            } catch (EvaluatorException e) {
                if (error == null) {
                    error = "";
                }
                error += "Error in connector \"" + getName() + "\" at Javascript:\nError on line " + e.lineNumber() + ": " + e.getMessage() + ".\n\n";
            } catch (Exception e) {
                if (error == null) {
                    error = "";
                }
                error += "Error in connector \"" + getName() + "\" at Javascript:\nUnknown error occurred during validation.";
            }

            Context.exit();
        }

        return error;
    }

    @Override
    public List<String> getScripts(ConnectorProperties properties) {
        JavaScriptDispatcherProperties props = (JavaScriptDispatcherProperties) properties;

        List<String> scripts = new ArrayList<String>();

        scripts.add(props.getScript());

        return scripts;
    }

    // @formatter:off
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jsLabel = new javax.swing.JLabel();
        javaScriptTextScrollPane = new com.mirth.connect.client.ui.components.rsta.MirthRTextScrollPane(ContextType.DESTINATION_DISPATCHER);

        setBackground(new java.awt.Color(255, 255, 255));
        setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));

        jsLabel.setText("JavaScript:");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jsLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(javaScriptTextScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 327, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jsLabel)
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addComponent(javaScriptTextScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 259, Short.MAX_VALUE))
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents
    // @formatter:on

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private com.mirth.connect.client.ui.components.rsta.MirthRTextScrollPane javaScriptTextScrollPane;
    private javax.swing.JLabel jsLabel;
    // End of variables declaration//GEN-END:variables
}
